// SpinTester.h: interface for the CSpinTester class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SPINTESTER_H__27464FAF_493A_4374_98C0_E5F3EAE02009__INCLUDED_)
#define AFX_SPINTESTER_H__27464FAF_493A_4374_98C0_E5F3EAE02009__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "SpinTestResults.h"

class CSpinTester
{
public:
	CSpinTester();
	virtual ~CSpinTester();

	bool Initialize( CSession* pSession, int nSlotGutID, LPCTSTR szServer, UINT nPort );
	bool Spin( DWORD nNumSpins, DWORD nNumLines, DWORD nBetPerLine );
	bool IsSpinning() const;
	bool AreResultsReady() const;
	bool DidResultsFail() const;
	const CSpinTestResults* GetResults() const;
	void ResetResults();

private:
	bool LoadMachineID( CSpinTestInitializeMessage& msgInit );
	bool LoadSubstNoteID( CSpinTestInitializeMessage& msgInit );
	bool LoadNumClientDataSets( CSpinTestInitializeMessage& msgInit );
	bool LoadServerInitParams( CSpinTestInitializeMessage& msgInit );

	bool SendPacketToServer( void* pPacketData, int nPacketSize );
	bool SendClientData();
	bool SendGameModeSummaryDataRequest( BYTE byGameMode );
	bool SendPayoutTypeDetailDataRequest( BYTE byGameMode, BYTE byPayoutType );
	bool SendBonusGameTypeDetailDataRequest( BYTE byBonusGameType );

	bool ReceivePacketFromServer();
	bool ReceiveAckMessage();
	bool ReceiveSummaryData();
	bool ReceiveGameModeSummaryData( BYTE byGameMode );
	bool ReceivePayoutTypeDetailData( BYTE byGameMode, BYTE byPayoutType );
	bool ReceiveBonusGameTypeDetailData( BYTE byBonusGameType );
	bool ReceiveSpinResults();

	bool InitializeSocket();
	bool InitializeServer();
	bool InitializeWorkerThread();

	bool SpinServer();

	enum WorkerThreadCommand
	{
		wtcInvalid,
		wtcInitializeServer,
		wtcSpinServer,
		wtcStopThread
	};

	DWORD WorkerThreadProc();

	static DWORD WINAPI _ThreadProc( LPVOID pThis )
	{
		return ((CSpinTester*)pThis)->WorkerThreadProc();
	}

	bool SendCommandToWorkerThread( WorkerThreadCommand wtc );

private:
	int m_nSlotGutID;
	CSocket* m_pSocket;
	CString m_strServer;
	UINT m_nPort;
	HANDLE m_hWorkerThread;
	HANDLE m_hWorkerThreadSignal;
	HANDLE m_hMainThreadSignal;
	volatile WorkerThreadCommand m_eWorkerThreadCommand;
	volatile bool m_bWorkerThreadRV;
	volatile DWORD m_nNumSpinsPending;
	DWORD m_nNumLines;
	DWORD m_nBetPerLine;
	DWORD m_dwMainThreadID;
	CSpinTestResults m_Results;
	BYTE m_byReceiveBuffer[256];
	CSession* m_pSession;
	volatile bool m_bResultsReady;
	volatile bool m_bResultsFailed;
};

#endif // !defined(AFX_SPINTESTER_H__27464FAF_493A_4374_98C0_E5F3EAE02009__INCLUDED_)
